package czk.concrent.reentrantWriteAndReadlock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 互斥锁的研究与代码
 *
 * @Author:ChenZhangKun
 * @Date: 2020/7/15 22:53
 */
public class ReentrantWriteAndReadLockDemo {
    public static void main(String[] args) throws InterruptedException {
        // 读读可以并发，读写和写写不支持并发
        DataContainer dataContainer = new DataContainer();
        new Thread(() -> {
            dataContainer.read();
        }).start();
        Thread.sleep(100);
        new Thread(() -> {
            dataContainer.read();
        }).start();
    }
}

class DataContainer {
    Object data;
    // 读写锁
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    // 创建读锁
    private ReentrantReadWriteLock.ReadLock r = reentrantReadWriteLock.readLock();
    // 创建写锁
    private ReentrantReadWriteLock.WriteLock w = reentrantReadWriteLock.writeLock();

    // 读方法
    // 两个线程同时去获取是不会阻塞
    public String read() {
        try {
            System.out.println("获取读锁");
            r.lock();
            System.out.println("获取读锁成功");
            Thread.sleep(2000);
            return "成功";
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            r.unlock();
            System.out.println("释放读锁");
        }
        return null;
    }

    // 写锁
    public void write() {
        try {
            System.out.println("获取写锁");
            w.lock();

            try {
                Thread.sleep(2000);
                System.out.println("获取写锁成功");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } finally {
            w.unlock();
        }
    }
}
